package com.funny.encrypt.interceptor;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import com.funny.encrypt.anno.DuyanSensitive;
import com.funny.encrypt.anno.NeedDecrypt;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Properties;

/**
 * @author fanxiao  2022/1/17
 * @since 1.0.0
 */

@Intercepts({
		@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
public class ResultSetDecryptInterceptor implements Interceptor {

	private static final String KEY = "HelloWorldQQQQQQ";

	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		// 获取查询的结果
		Object resultObject = invocation.proceed();
		if (Objects.isNull(resultObject)) {
			return null;
		}
		if (resultObject instanceof ArrayList) {
			ArrayList resultList = (ArrayList) resultObject;
			if (!CollectionUtils.isEmpty(resultList) && needDecryptIfNecessary(resultList.get(0))) {
				for (Object result : resultList) {
					//逐一解密
					needDecrypt(result);
				}
			}
		} else {
			if (needDecryptIfNecessary(resultObject)) {
				needDecrypt(resultObject);
			}
		}
		return resultObject;
	}

	private boolean needDecryptIfNecessary(Object object) {
		Class<?> objectClass = object.getClass();
		DuyanSensitive annotation = AnnotationUtils.findAnnotation(objectClass, DuyanSensitive.class);
		return Objects.nonNull(annotation);
	}


	private void needDecrypt(Object resultObject) throws IllegalAccessException {
		Class<?> resultClass = resultObject.getClass();
		Field[] declaredFields = resultClass.getDeclaredFields();
		for (Field field : declaredFields) {
			NeedDecrypt annotation = field.getAnnotation(NeedDecrypt.class);
			if (!Objects.isNull(annotation)) {
				field.setAccessible(true);
				Object object = field.get(resultObject);
				//只支持String的解密
				if (object instanceof String) {
					String value = (String) object;
					//对注解的字段进行逐一解密
					field.set(resultObject, decrypt(value));
				}
			}
		}
	}

	private String decrypt(String value){
		SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, KEY.getBytes());
		return aes.decryptStr(value, CharsetUtil.CHARSET_UTF_8);
	}

	  public static void main(String[] args) {
		  // 25460cd344335ac8ff936e9f35c19fb7
		  SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, KEY.getBytes());
//		  String hello = aes.encryptHex("Hello");
//		  System.out.println(hello);
		  String s = aes.decryptStr("7a29afccd8d8af2022d49ee95d4a25d5");
    System.out.println(s);
	  }

	@Override
	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}

	@Override
	public void setProperties(Properties properties) {

	}
}